<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模拟Vue.assetRegisters(Vue)</title>
</head>
<body>
    <div id="app"></div>
    <template id='Comp'>
        <div>
            haha
        </div>
    </template>
</body>
<script>
    const ASSET_TYPES = ['directive','component','filter']
    // 判断是否是原始的Object
    const _toString = Object.prototype.toString
    function isPlainObject(obj){
        return _toString.call(obj)==='[object Object]'
    }
    function initMixin(){
        Vue.prototype._init = function(options){
            console.log('假装写了_init，以后补上')
        }
    }
    function initExtend (Vue){
        Vue.extend = function (){
            const Super = this
            const Sub = function Sub (options){
                this._init(options)
            }
            Sub.prototype = Object.create(Super.prototype)
            Sub.prototype.constructor = Sub
            return Sub
        }
    }
    // -----------------------------------------
    function Vue(options){
        this._init(options)
    }
    initMixin()
    initExtend(Vue)
    initAssetRegisters(Vue)
    function initAssetRegisters(Vue){
        // eg: Vue.component(id,{template:'#tem'}) ;Vue实例options里面的components:{Comp}
        ASSET_TYPES.forEach(type=>{
            Vue[type] = function (id,definition){
                if(definition){
                    return this.options[type + 's'][id]
                }else{
                    if(type==='component' && isPlainObject(definition)){
                        definition.name = definition.name || id
                        // 把组件配置转换为组件的构造函数
                        definition = Vue.extend(definition)
                    }
                    if(type === 'directive' && typeof definition === 'function'){
                        definition = {
                            bind:definition,
                            update:definition
                        }
                    }
                    // 全具注册，存储资源并赋值
                    // this.options['components']['Comp'] = definition
                    return definition
                }
            }
        })
    }
    let vm = new Vue({
        el:'#app',
        components:{
            Comp
        }
    })
    
</script>
</html>